<?php

namespace app\common\service;

use think\admin\extend\HttpExtend;
use think\admin\model\SystemBase;
use think\facade\Cache;

/**
 * CrmebService
 * @package app\common\service
 * @Description 商城接口服务
 * @author wangqinghui
 * @date 2024-10-14 14:50
 */
class CrmebService
{

    // 接口地址
    protected $api_url = '';

    // 应用ID
    protected $appid = '';

    // 应用密钥
    protected $appsecret = '';

    // 缓存key
    protected $cache_key = 'crmeb_';

    // 账号token
    protected $app_token = '';

    // 错误信息
    protected $err_msg = '';

    // 服务实例
    protected static $handler = null;

    // 获取token的url
    protected $access_token_url = '/outapi/access_token';

    // 刷新token的url
    protected $refresh_token_url = '/outapi/refresh_token';

    // 添加用户url
    protected $add_user_url = '/outapi/user';

    // 获取分类url
    protected $category_url = '/outapi/category/list';

    // 添加商品url
    protected $add_product_url = '/outapi/product';

    // 更新商品url
    protected $update_product_url = '/outapi/product/';

    // 同步库存url
    protected $sync_stock_url = '/outapi/product/stock/upload';

    // 订单列表url
    protected $order_list_url = '/outapi/order/list';

    /**
     * 实例化接口服务
     * @Description
     * @author wangqinghui
     * @date 2025-01-09 15:48
     * @return CrmebService
     */
    public static function getInstance() : CrmebService
    {
        if (is_null(self::$handler)) {
            self::$handler = new self();
        }
        return self::$handler;
    }

    /**
     * 获取错误信息
     * @Description
     * @author wangqinghui
     * @date 2025-01-09 15:51
     * @return void
     */
    public function getError()
    {
        return $this->err_msg;
    }

    /**
     * 设置配置参数
     * @param array $config
     * @Description
     * @author wangqinghui
     * @date 2025-01-09 15:30
     * @return CrmebService
     */
    public function setConfig(array $config = []) : CrmebService
    {
        if(!empty($config)){
            $config_data = [
                'crmeb_url' => $config['url'] ?? '',
                'crmeb_appid'   =>  $config['client_id'] ?? '',
                'crmeb_appsecret'   =>  $config['api_key'] ?? '',
            ];
        }else{
            $code_arr = ['crmeb_url', 'crmeb_appid', 'crmeb_appsecret'];
            $map = [
                ['type', '=', '官网配置'],
                ['status', '=', 1],
                ['deleted', '=', 0],
                ['code', 'in', $code_arr]
            ];
            $config_data = SystemBase::mk()->where($map)->column('content', 'code');
        }
        $this->api_url = $config_data['crmeb_url'] ?? '';
        $this->appid = $config_data['crmeb_appid'] ?? '';
        $this->appsecret = $config_data['crmeb_appsecret'] ?? '';
        return $this;
    }

    /**
     * getToken
     *
     * @Description 获取token
     * @author wangqinghui
     * @date 2024-10-14 16:47
     * @return CrmebService
     */
    public function getToken() : CrmebService
    {
        $token_key = $this->cache_key.'token';
        $token_arr = Cache::get($token_key);
        if(empty($token_arr)){
            $token_url = $this->api_url. $this->access_token_url;
            $params = [
                'appid' => $this->appid,
                'appsecret' => $this->appsecret
            ];
            $ret = HttpExtend::post($token_url, $params);
            $ret = !empty($ret) ? json_decode($ret, 1) : [];
            if(!empty($ret['status']) && ($ret['status'] == 200) && !empty($ret['data'])){
                $token_arr = [
                    'token' => $ret['data']['access_token'],
                    'exp' => $ret['data']['exp_time']
                ];
                // 缓存token
                Cache::set($token_key, $token_arr, $token_arr['exp'] - time());
                // 设置token
                $this->app_token = $token_arr['token'];
            }
        }else{
            // 如果缓存中的token即将过期（例如，剩余时间少于5分钟），则刷新token
            if ($token_arr['exp'] - time() < 300) {
                // 发起请求刷新token
                $refresh_token_url = $this->api_url. $this->refresh_token_url;
                $params = [
                    'access_token' => $token_arr['token']
                ];
                $ret = HttpExtend::post($refresh_token_url, $params);
                $ret = !empty($ret) ? json_decode($ret, 1) : [];
                if(!empty($ret['status']) && ($ret['status'] == 200) && !empty($ret['data'])){
                    $token_arr = [
                        'token' => $ret['data']['access_token'],
                        'exp' => $ret['data']['exp_time']
                    ];
                    // 更新缓存中的token，并设置新的过期时间
                    Cache::set($token_key, $token_arr, $token_arr['exp'] - time());
                    // 设置token
                    $this->app_token = $token_arr['token'];
                }
            }else{
                // 如果缓存中的token尚未过期，直接使用缓存中的token
                $this->app_token = $token_arr['token'];
            }
        }
        
        return $this;
    }

    /**
     * 添加用户
     * @param array $user
     * @Description
     * @author wangqinghui
     * @date 2025-01-09 16:13
     * @return array
     */
    public function addUser(array $user = []) : array
    {
        $ret_info = ['code' => 0, 'data' => []];
        if(empty($this->api_url)){
            $this->err_msg = 'crmeb配置信息有误';
            return $ret_info;
        }
        if(empty($this->app_token)){
            $this->err_msg = 'token获取失败';
            return $ret_info;
        }
        $add_user_url = $this->api_url. $this->add_user_url;
        $params = [
            'real_name' => $user['true_name'] ?? '',
            'phone' => $user['mobile'] ?? '',
            'mark' => 'erp实训客户',
            'pwd' => $user['password_plaintext'] ?? '',
            'level' => 0,
            'spread_open'   =>  0,
            'is_promoter'   =>  0,
            'status'    =>  1,
        ];

        // 设置请求头
        $header_arr = [
            'Authori-Zation:Bearer '.$this->app_token,
        ];
        $option = [
            'headers'  =>  $header_arr
        ];
        $ret = HttpExtend::post($add_user_url, $params, $option);
        $ret = !empty($ret) ? json_decode($ret, 1) : [];
        if(empty($ret['status']) || ($ret['status'] != 200)){
            $this->err_msg = $ret['msg'] ?? '注册商城用户失败';
            return $ret_info;
        }
        $ret_info['code'] = 1;
        return $ret_info;
    }

    /**
     * 获取分类列表
     * @Description
     * @author wangqinghui
     * @date 2025-01-09 16:15
     * @return array
     */
    public function getCategoryList() : array
    {
        $ret_info = ['code' => 0, 'data' => []];
        if(empty($this->api_url)){
            $this->err_msg = 'crmeb配置信息有误';
            return $ret_info;
        }
        if(empty($this->app_token)){
            $this->err_msg = 'token获取失败';
            return $ret_info;
        }
        $get_category_url = $this->api_url. $this->category_url;
        $params = [];

        // 设置请求头
        $header_arr = [
            'Authori-Zation:Bearer '.$this->app_token,
        ];
        $option = [
            'headers'  =>  $header_arr
        ];
        $ret = HttpExtend::get($get_category_url, $params, $option);
        $ret = !empty($ret) ? json_decode($ret, 1) : [];
        if(empty($ret['status']) || ($ret['status'] != 200)){
            $this->err_msg = $ret['msg'] ?? '获取分类失败';
            return $ret_info;
        }
        $ret_info['code'] = 1;
        $ret_info['data'] = $ret['data'] ?? [];
        return $ret_info;
    }

    /**
     * 添加商品
     * @param array $product_data
     * @Description
     * @author wangqinghui
     * @date 2025-01-11 09:25
     * @return array
     */
    public function addProduct(array $product_data = []) : array
    {
        $ret_info = ['code' => 0, 'data' => []];
        if(empty($this->app_token)){
            $this->err_msg = 'token获取失败';
            return $ret_info;
        }
        if(empty($product_data)){
            $this->err_msg = '商品数据为空';
            return $ret_info;
        }
        $add_product_url = $this->api_url. $this->add_product_url;
        $params = $product_data;

        // 设置请求头
        $header_arr = [
            'Authori-Zation:Bearer '.$this->app_token,
        ];
        $option = [
            'headers'  =>  $header_arr,
            'data' => http_build_query($params)
        ];
        $ret = HttpExtend::request('post', $add_product_url, $option);
        $ret = !empty($ret) ? json_decode($ret, 1) : [];
        if(empty($ret['status']) || ($ret['status'] != 200)){
            $this->err_msg = $ret['msg'] ?? '添加商品失败';
            return $ret_info;
        }
        $ret_info['code'] = 1;
        $ret_info['data'] = isset($ret['data']['id']) ? $ret['data']['id'] : 0;
        return $ret_info;
    }

    /**
     * 修改商品
     * @param integer $product_id
     * @param array $product_data
     * @Description
     * @author wangqinghui
     * @date 2025-01-11 09:33
     * @return array
     */
    public function updateProduct(int $product_id = 0, array $product_data = []) : array
    {
        $ret_info = ['code' => 0, 'data' => []];
        if(empty($this->api_url)){
            $this->err_msg = 'crmeb配置信息有误';
            return $ret_info;
        }
        if(empty($this->app_token)){
            $this->err_msg = 'token获取失败';
            return $ret_info;
        }
        if(empty($product_id) || ($product_id <= 0)){
            $this->err_msg = '商品ID有误';
            return $ret_info;
        }
        if(empty($product_data)){
            $this->err_msg = '商品数据为空';
            return $ret_info;
        }
        $update_product_url = $this->api_url. $this->update_product_url.$product_id;
        $params = $product_data;

        // 设置请求头
        $header_arr = [
            'Authori-Zation:Bearer '.$this->app_token,
        ];
        $option = [
            'headers'  =>  $header_arr,
            'data'  =>  http_build_query($params)
        ];
        $ret = HttpExtend::request('put', $update_product_url, $option);
        $ret = !empty($ret) ? json_decode($ret, 1) : [];
        if(empty($ret['status']) || ($ret['status'] != 200)){
            $this->err_msg = $ret['msg'] ?? '修改商品失败';
            return $ret_info;
        }
        $ret_info['code'] = 1;
        $ret_info['data'] = [];
        return $ret_info;
    }

    /**
     * 同步商品库存
     * @param array $product_stock
     * @Description
     * @author wangqinghui
     * @date 2025-01-11 09:36
     * @return array
     */
    public function updateProductStock(array $product_stock = []) : array
    {
        $ret_info = ['code' => 0, 'data' => []];
        if(empty($this->api_url)){
            $this->err_msg = 'crmeb配置信息有误';
            return $ret_info;
        }
        if(empty($this->app_token)){
            $this->err_msg = 'token获取失败';
            return $ret_info;
        }
        if(empty($product_stock)){
            $this->err_msg = '商品库存数据为空';
            return $ret_info;
        }
        $update_product_stock_url = $this->api_url. $this->sync_stock_url;
        $params = [
            'items'  =>  $product_stock
        ];

        // 设置请求头
        $header_arr = [
            'Authori-Zation:Bearer '.$this->app_token,
        ];
        $option = [
            'headers'  =>  $header_arr,
            'data'  =>  http_build_query($params)
        ];
        $ret = HttpExtend::request('put', $update_product_stock_url, $option);
        $ret = !empty($ret) ? json_decode($ret, 1) : [];
        if(empty($ret['status']) || ($ret['status'] != 200)){
            $this->err_msg = $ret['msg'] ?? '同步商品库存失败';
            return $ret_info;
        }
        $ret_info['code'] = 1;
        $ret_info['data'] = [];
        return $ret_info;
    }

    /**
     * 获取订单列表
     * @param array $filter
     * @param integer $page
     * @param integer $limit
     * @Description
     * @author wangqinghui
     * @date 2025-01-11 10:01
     * @return array
     */
    public function getOrderList(array $filter = [],int $page = 1, int $limit = 200) : array
    {
        $ret_info = ['code' => 0, 'data' => []];
        if(empty($this->api_url)){
            $this->err_msg = 'crmeb配置信息有误';
            return $ret_info;
        }
        if(empty($this->app_token)){
            $this->err_msg = 'token获取失败';
            return $ret_info;
        }
        if(empty($page) || ($page <= 0)){
            $this->err_msg = '分页参数有误';
            return $ret_info;
        }
        if(empty($limit) || ($limit <= 0)){
            $this->err_msg = '分页条数参数有误';
            return $ret_info;
        }
        $get_order_list_url = $this->api_url. $this->order_list_url;
        $params = array_merge(['page' => $page, 'limit' => $limit], $filter);

        // 设置请求头
        $header_arr = [
            'Authori-Zation:Bearer '.$this->app_token,
        ];
        $option = [
            'headers'  =>  $header_arr,
        ];
        $ret = HttpExtend::get($get_order_list_url, $params, $option);
        $ret = !empty($ret) ? json_decode($ret, 1) : [];
        if(empty($ret['status']) || ($ret['status'] != 200)){
            $this->err_msg = $ret['msg'] ?? '获取订单列表失败';
            return $ret_info;
        }
        $ret_info['code'] = 1;
        $ret_info['data'] = $ret['data'] ?? [];
        return $ret_info;
    }
}
